using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Repositories;
using UniversalAdmin.Infrastructure.Data.Contexts;

namespace UniversalAdmin.Infrastructure.Repositories;

public class OperationLogRepository : Repository<OperationLog>, IOperationLogRepository
{
    public OperationLogRepository(ApplicationDbContext context) : base(context)
    {
    }

    public async Task<(IEnumerable<OperationLog> Logs, int TotalCount)> GetPagedAsync(int page, int pageSize, string? userId = null, string? operation = null, DateTime? startDate = null, DateTime? endDate = null)
    {
        var query = _context.OperationLogs.AsQueryable();

        if (!string.IsNullOrEmpty(userId))
        {
            if (Guid.TryParse(userId, out var userIdGuid))
            {
                query = query.Where(l => l.UserId == userIdGuid);
            }
        }

        if (!string.IsNullOrEmpty(operation))
        {
            query = query.Where(l => l.Operation.Contains(operation));
        }

        if (startDate.HasValue)
        {
            query = query.Where(l => l.CreatedAt >= startDate.Value);
        }

        if (endDate.HasValue)
        {
            query = query.Where(l => l.CreatedAt <= endDate.Value);
        }

        var totalCount = await query.CountAsync();
        var logs = await query
            .OrderByDescending(l => l.CreatedAt)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();

        return (logs, totalCount);
    }

    public async Task<IEnumerable<OperationLog>> GetByUserAsync(Guid userId, int page, int pageSize)
    {
        return await _context.OperationLogs
            .Where(l => l.UserId == userId)
            .OrderByDescending(l => l.CreatedAt)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }

    public async Task<IEnumerable<OperationLog>> GetByOperationAsync(string operation, int page, int pageSize)
    {
        return await _context.OperationLogs
            .Where(l => l.Operation.Contains(operation))
            .OrderByDescending(l => l.CreatedAt)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }

    public async Task<IEnumerable<OperationLog>> GetByDateRangeAsync(DateTime startDate, DateTime endDate, int page, int pageSize)
    {
        return await _context.OperationLogs
            .Where(l => l.CreatedAt >= startDate && l.CreatedAt <= endDate)
            .OrderByDescending(l => l.CreatedAt)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }
}